package com.suns.controller;

import com.github.pagehelper.PageInfo;
import com.google.code.kaptcha.Constants;
import com.suns.domain.Admin;
import com.suns.domain.Application;
import com.suns.domain.Income;
import com.suns.domain.User;
import com.suns.service.*;
import com.suns.util.CookieUtil;
import com.suns.util.RedisUtil;
import com.suns.util.TokenGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

@Controller
@RequestMapping("/admins")
public class AdminController {
    @Autowired
    private AdminService adminService;
    @Autowired
    private UserService userService;
    @Autowired
    private IncomeService incomeService;
    @Autowired
    private ApplicationService applicationService;
    @Autowired
    private RedisUtil redisUtil;
    @PostMapping("/login")
    @ResponseBody
    public Result login(@RequestParam String tel, @RequestParam String pwd, @RequestParam String verifyCode,
                        @RequestParam int rememberMe,
                        HttpSession session, HttpServletResponse response) throws Exception {
        String captcha = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (verifyCode.equals(captcha)) {
            Admin admin = adminService.adminlogin(tel,pwd);
            Integer code = admin!=null ? Code.ADMIN_LOGIN_OK : Code.ADMIN_LOGIN_ERR;
            String msg = admin!=null ? "登录成功!" : "账号或密码错误!";
            if (admin!=null) {
                // 生成随机的 token
                String token = TokenGenerator.generateToken();
                // 将 token 和用户账号保存到 Redis 缓存中，设置过期时间为七天
                String cookieValue = CookieUtil.encrypt(admin.toString(), "A_cookie_key");
                redisUtil.set(token, cookieValue, 60 * 60 * 24 * 7);
                session.setAttribute("A_TOKEN",token);
                // 如果勾选了“记住我”选项，则将用户信息存储到cookie中
                boolean RM;
                RM= rememberMe == 1;
                if (RM) {
                    Cookie cookie1=new Cookie("A_TOKEN",token);
                    cookie1.setMaxAge(60 * 60 * 24 * 7); // 设置cookie过期时间为七天
                    cookie1.setPath("/"); // 设置cookie的作用路径为整个网站
                    response.addCookie(cookie1);
                    Cookie cookie = new Cookie("A_rememberMe", cookieValue);
                    cookie.setMaxAge(60 * 60 * 24 * 7);
                    cookie.setPath("/");
                    response.addCookie(cookie);
                }
            }
            return new Result(code, tel, msg);
        } else {
            return new Result(0, tel, "验证码错误!");
        }
    }

    @GetMapping("/autologin")
    public String autoLogin(HttpServletRequest request,HttpServletResponse response) throws Exception {
        String token = (String)request.getSession().getAttribute("A_TOKEN");
        if(token==null){
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    // 找到了名为rememberMe的cookie
                    if ("A_rememberMe".equals(cookie.getName())) {
                        String decryptValue = CookieUtil.decrypt(cookie.getValue(), "A_cookie_key");
                        Admin C_admin=Admin.fromJsonString(decryptValue);
                        // 从redis缓存中获取用户信息
                        token = getA_token(request);
                        Admin admin = null;
                        if(token!=null){
                            String json =CookieUtil.decrypt(redisUtil.get(token),"A_cookie_key");
                            admin=Admin.fromJsonString(json);
                        }
                        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
                        if (admin != null && C_admin != null) {
                            if (Objects.equals(C_admin.getTel(), admin.getTel())&&Objects.equals(passwordEncoder.encode(C_admin.getPwd()),passwordEncoder.encode(admin.getPwd()))){
//                                若登录成功则更新Cookie的值
                                Admin admin1 = adminService.adminlogin(admin.getTel(),admin.getPwd());
                                if(admin1!=null){
                                    String NewCookieValue = CookieUtil.encrypt(admin1.toString(), "A_cookie_key");
                                    cookie.setValue(NewCookieValue);
                                    response.addCookie(cookie);
                                }else {
                                    return "AdminLogin";
                                }
                                return "redirect:/admins/AdminMain";
                            }
                        } else {
                            // 如果cookie的信息与redis缓存的信息不一致，则删除cookie
                            cookie.setMaxAge(0);
                            cookie.setPath("/");
                            break;
                        }
                    }
                }
            }
        }else {
            return "redirect:/admins/AdminMain";
        }
        return "AdminLogin";
    }

    @GetMapping("/logout")
    public String logout(Model model,HttpServletResponse response,HttpServletRequest request){
       String token=getA_token(request);
        String admin=null;
        if(token!=null){
            redisUtil.del(token);
            Cookie cookie = new Cookie("A_rememberMe", null);
            cookie.setMaxAge(0);
            cookie.setPath("/");
            response.addCookie(cookie);
            Cookie cookie1 = new Cookie("A_TOKEN", null);
            cookie1.setMaxAge(0);
            cookie1.setPath("/");
            response.addCookie(cookie1);
            admin=redisUtil.get(token);
            HttpSession session = request.getSession(false);
            if(session != null){
                session.removeAttribute("A_TOKEN");
            }
        }
        Integer code= admin==null ? Code.ADMIN_LOGOUT_OK : Code.ADMIN_LOGOUT_ERR;
        String msg= admin==null ? "退出成功!" : "网络异常,请稍后重试!";
        model.addAttribute("Result", new Result(code,null,msg));
        return "AdminLogin";
    }



    @GetMapping("/A_AdminInfo")
    public String A_AdminInfo(Model model ,HttpServletRequest request) throws Exception {
        String token=getA_token(request);
        String json =CookieUtil.decrypt(redisUtil.get(token),"A_cookie_key");
        Admin admin=Admin.fromJsonString(json);
        Integer code= admin!=null ? Code.GET_OK : Code.GET_ERR;
        String msg= admin!=null ? "管理员信息获取成功!" : "管理员信息获取失败!";
        model.addAttribute("Result", new Result(code,admin,msg));
        return "A_AdminInfo";
    }

    @PostMapping("/UpAdminInfo")
    @ResponseBody
    public Result UpAdminInfo(@RequestParam String pwd, @RequestParam(defaultValue = "null") String Npwd,
                              @RequestParam String verifyCode, @RequestParam String name ,
                              @RequestParam Integer age,@RequestParam String gender,
                              @RequestParam String tel,HttpSession session,HttpServletRequest request,HttpServletResponse response) throws Exception {
        String captcha = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (verifyCode.equals(captcha)) {
            Npwd = Objects.equals(Npwd, "null") ? null : Npwd;
            boolean flag=adminService.updateAdmin(name,tel,pwd,age,gender,Npwd);
            if(flag){
//                修改成功后更新redis 和cookie
                String token=getA_token(request);
                if(token!=null){
                    redisUtil.del(token);
                }
                String p= Npwd!=null ? Npwd : pwd;
                Admin admin = adminService.adminlogin(tel,p);
                //更新redis
                String cookieValue = CookieUtil.encrypt(admin.toString(), "A_cookie_key");
                redisUtil.set(token, cookieValue, 60 * 60 * 24 * 7);
                Cookie[] cookies = request.getCookies();
                if (cookies != null) {
                    for (Cookie cookie : cookies) {
                        // 找到了名为rememberMe的cookie,则更新Cookie
                        if ("A_rememberMe".equals(cookie.getName())) {
                            Cookie cookie1=new Cookie("A_TOKEN",token);
                            cookie1.setMaxAge(60 * 60 * 24 * 7); // 设置cookie过期时间为七天
                            cookie1.setPath("/"); // 设置cookie的作用路径为整个网站
                            response.addCookie(cookie1);
                            cookie = new Cookie("A_rememberMe", cookieValue);
                            cookie.setMaxAge(60 * 60 * 24 * 7);
                            cookie.setPath("/");
                            response.addCookie(cookie);
                        }
                    }
                }
            }
            Integer code=flag ? Code.ADMIN_UPDATEINFO_OK : Code.ADMIN_UPDATEINFO_ERR;
            String msg=flag ? "信息修改成功!" : "密码错误,请重试!";
            return new  Result(code,tel,msg);
        }else {
            return new  Result(0,tel,"验证码错误,请重试!");
        }
    }

    @GetMapping("/AdminMain")
    public String AdminMain(Model model ,HttpServletRequest request) throws Exception {
        String token=getA_token(request);
        if(token!=null){
            String json =CookieUtil.decrypt(redisUtil.get(token),"A_cookie_key");
            Admin admin=Admin.fromJsonString(json);
            Integer code= admin!=null ? Code.LOGIN_OK : Code.GET_ERR;
            String msg= admin!=null ? "管理员信息获取成功!" : "管理员信息获取失败!";
            model.addAttribute("Result", new Result(code,admin,msg));
        }
        return "AdminMain";
    }

    @GetMapping("/HelloAdmin")
    public String HelloAdmin(){
        return "HelloAdmin";
    }
    @GetMapping("/A_UserList")
    public String A_UserList(@RequestParam(defaultValue = "1") int pageNum,
                             @RequestParam(defaultValue = "5") int pageSize,
                             @RequestParam(defaultValue = "null") String keywords,
                             Model model){
        PageInfo<User> page = userService.getPageUsers(pageNum<=1 ? 1 : pageNum, pageSize,keywords);
        Integer code=page!=null ? Code.GET_OK : Code.GET_ERR;
        String msg=page!=null ? "用户列表获取成功!" : "用户列表获取失败!";
        model.addAttribute("Result", new Result(code,page.getPages(),msg));
        model.addAttribute("page", page);
        model.addAttribute("keywords", Objects.equals(keywords, "null") ? null : keywords);
        return "A_UserList";
    }

    @PostMapping("/A_UserDel")
    @ResponseBody
    public Result A_UserDel(@RequestParam String idList, @RequestParam String verifyCode,
                            HttpSession session){
        String captcha = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (verifyCode.equals(captcha)) {
            String[] tids=idList.split(",");
            List<Integer> ids = new ArrayList<>();
            for (String tid : tids) {
                ids.add(Integer.parseInt(tid));
            }
            boolean flag=false;
            if (!ids.isEmpty()){
                flag= userService.delUsers(ids);
            }
            Integer code=flag ? Code.DELETE_OK : Code.DELETE_ERR;
            String msg=flag ? "批量删除成功!" : "批量删除失败,请重试!";
            return new Result(code,idList,msg);
        }
        return new Result(0,idList,"验证码错误!");
    }

    @GetMapping("/A_AdminList")
    public String A_AdminList(@RequestParam(defaultValue = "1") int pageNum,
                             @RequestParam(defaultValue = "5") int pageSize,
                             @RequestParam(defaultValue = "null") String keywords,
                             Model model){
        PageInfo<Admin> page = adminService.getPageAdmins(pageNum<=1 ? 1 : pageNum, pageSize,keywords);
        Integer code=page!=null ? Code.GET_OK : Code.GET_ERR;
        String msg=page!=null ? "管理员列表获取成功!" : "管理元列表获取失败!";
        model.addAttribute("Result", new Result(code,page.getPages(),msg));
        model.addAttribute("page", page);
        model.addAttribute("keywords", Objects.equals(keywords, "null") ? null : keywords);
        return "A_AdminList";
    }

    @GetMapping("/A_C_IncomeList")
    public String A_C_IncomeList(@RequestParam(defaultValue = "1") int pageNum,
                              @RequestParam(defaultValue = "5") int pageSize,
                              @RequestParam(defaultValue = "null") String keywords,
                              Model model){
        PageInfo<Income> page = incomeService.getPage_C_Income(pageNum<=1 ? 1 : pageNum, pageSize,keywords);
        Integer code=page!=null ? Code.GET_OK : Code.GET_ERR;
        String msg=page!=null ? "收入列表获取成功!" : "收入列表获取失败!";
        model.addAttribute("Result", new Result(code,page.getPages(),msg));
        model.addAttribute("page", page);
        model.addAttribute("keywords", Objects.equals(keywords, "null") ? null : keywords);
        return "A_C_IncomeList";
    }

    @GetMapping("/A_Y_IncomeList")
    public String A_Y_IncomeList(@RequestParam(defaultValue = "1") int pageNum,
                                 @RequestParam(defaultValue = "5") int pageSize,
                                 @RequestParam(defaultValue = "null") String keywords,
                                 Model model){
        PageInfo<Income> page = incomeService.getPage_Y_Income(pageNum<=1 ? 1 : pageNum, pageSize,keywords);
        Integer code=page!=null ? Code.GET_OK : Code.GET_ERR;
        String msg=page!=null ? "收入列表获取成功!" : "收入列表获取失败!";
        model.addAttribute("Result", new Result(code,page.getPages(),msg));
        model.addAttribute("page", page);
        model.addAttribute("keywords", Objects.equals(keywords, "null") ? null : keywords);
        return "A_Y_IncomeList";
    }

    @GetMapping("/A_TJ")
    public String A_TJ(@RequestParam(defaultValue = "null") String day,
                       @RequestParam(defaultValue = "null") String mouth,
                       Model model){
        if (Objects.equals(day, "null") && Objects.equals(mouth, "null")){
            day=getCurrentDateAsString();
        }
        BigDecimal C_income = incomeService.get_Income("次卡",day,mouth);
        BigDecimal C_outcome= applicationService.get_Outcome("次卡",day,mouth);
        BigDecimal Y_income = incomeService.get_Income("月卡",day,mouth);
        BigDecimal Y_outcome= applicationService.get_Outcome("月卡",day,mouth);
        BigDecimal income =C_income.add(Y_income);
        BigDecimal outcome=C_outcome.add(Y_outcome);
        boolean flag= Y_income != null && Y_outcome != null;
        String msg= flag ? "统计信息获取成功!" : "统计信息获取失败!";
        Integer code= flag ? Code.GET_OK : Code.GET_ERR;
        model.addAttribute("Result", new Result(code,income,msg));
        model.addAttribute("income", income);
        model.addAttribute("outcome",outcome);
        model.addAttribute("C_income", C_income);
        model.addAttribute("C_outcome",C_outcome);
        model.addAttribute("Y_income", Y_income);
        model.addAttribute("Y_outcome",Y_outcome);
        day= Objects.equals(day, "null") ? null : day;
        mouth =Objects.equals(mouth,"null") ? null : mouth;
        model.addAttribute("day",day);
        model.addAttribute("mouth",mouth);
        return "A_TJ";
    }

    @PostMapping("/A_SH_Recharge")
    @ResponseBody
    public Result A_SH_Recharge(@RequestParam String idList,
                                @RequestParam String telList,
                                @RequestParam String mnList,
                                @RequestParam Integer sh){
        System.out.println(sh);
        String[] aids=idList.split(",");
        List<Integer> ids=new ArrayList<>();
        for(String id:aids){
            ids.add(Integer.parseInt(id));
        }
        String[] atels=telList.split(",");
        List<String> tels = new ArrayList<>(Arrays.asList(atels));

        String[] amns=mnList.split(",");
        List<Integer> mns = new ArrayList<>();
        for (String mn : amns) {
            mns.add(Integer.parseInt(mn));
        }
        boolean flag=false;
        if (!tels.isEmpty()&&!mns.isEmpty()&&tels.size()==mns.size()){
            try {
                flag= applicationService.delaps(ids,tels,mns,sh);
            }catch (Exception ex){
                //记录日志
                System.out.println(ex.getMessage());
            }
        }
        Integer code=flag ? Code.ADMIN_SH_OK : Code.ADMIN_SH_ERR;
        String msg=flag ? "批量审批成功!" : "批量审批失败,请重试!";
        return new Result(code,telList,msg);
    }
    @GetMapping("/A_DS_Recharge")
    public String A_DS_Recharge(@RequestParam(defaultValue = "1") int pageNum,
                                @RequestParam(defaultValue = "5") int pageSize,
                                @RequestParam(defaultValue = "null") String keywords,
                                Model model){
        PageInfo<Application> page = applicationService.getPageAPList(pageNum<=1 ? 1 : pageNum, pageSize,keywords);
        Integer code=page!=null ? Code.GET_OK : Code.GET_ERR;
        String msg=page!=null ? "待审列表获取成功!" : "待审列表获取失败!";
        model.addAttribute("Result", new Result(code,page.getPages(),msg));
        model.addAttribute("page", page);
        model.addAttribute("keywords", Objects.equals(keywords, "null") ? null : keywords);
        return "A_DS_Recharge";
    }
    @GetMapping("/A_YS_Recharge")
    public String A_YS_Recharge(@RequestParam(defaultValue = "1") int pageNum,
                              @RequestParam(defaultValue = "5") int pageSize,
                              @RequestParam(defaultValue = "null") String keywords,
                              Model model){
        PageInfo<Application> page = applicationService.getPageaps(pageNum<=1 ? 1 : pageNum, pageSize,keywords);
        Integer code=page!=null ? Code.GET_OK : Code.GET_ERR;
        String msg=page!=null ? "已审批列表获取成功!" : "已审批列表获取失败!";
        model.addAttribute("Result", new Result(code,page.getPages(),msg));
        model.addAttribute("page", page);
        model.addAttribute("keywords", Objects.equals(keywords, "null") ? null : keywords);
        return "A_YS_Recharge";
    }

    //用来获取当前会话的token或者cookie中的token
    public static String getA_token(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        String token = (String)request.getSession().getAttribute("A_TOKEN");
        if(token==null){
            for (Cookie cookie1 : cookies) {
                if("A_TOKEN".equals(cookie1.getName())){
                    token = cookie1.getValue();
                }
            }
        }
        return token;
    }


    public static String getCurrentDateAsString() {
        LocalDate currentDate = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return currentDate.format(formatter);
    }
}
